#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

// int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutexattr_t *attr);  初始化互斥锁  参数 mutex:未初始化过互斥锁变量的地址 mutexattr：普通属性，NULL
// pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
// 也就是说，以上这句话等价于：
// pthread_mutex_t m;
// pthread_mutex_init(&m,NULL);

// int pthread_mutex_lock(pthread_mutex_t *mutex);    // 加锁     如果加锁失败，会阻塞
// int pthread_mutex_trylock(pthread_mutex_t *mutex); // 尝试加锁  如果加锁失败，直接返回，不会阻塞

// int pthread_mutex_unlock(pthread_mutex_t *mutex); // 解锁

// int pthread_mutex_destroy(pthread_mutex_t *mutex); // 销毁互斥锁

int g_val = 10;

void *start_routine1(void *mutex)
{
    pthread_mutex_lock(mutex); // 加锁
    g_val = 100;
    sleep(3);
    printf("start_routine1  %d\n", g_val);
    pthread_mutex_unlock(mutex); // 解锁
}

void *start_routine2(void *mutex)
{
    sleep(1);

    // 在实际项目里面不一定从子线程一开始到结束整个阶段占用资源 需要的时候加锁，不需要的时候解锁
    pthread_mutex_lock(mutex); // 加锁
    g_val = 200;
    printf("start_routine2  %d\n", g_val);
    pthread_mutex_unlock(mutex); // 解锁
}

int main()
{
    printf("main  %d\n", g_val);
    pthread_mutex_t mutex;
    pthread_mutex_init(&mutex, NULL);

    pthread_t thread1;
    pthread_create(&thread1, NULL, start_routine1, &mutex);

    pthread_t thread2;
    pthread_create(&thread2, NULL, start_routine2, &mutex);

    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    return 0;
}